package com.aischool.utils;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

import org.apache.commons.lang.StringUtils;

public class ImageUtil {
	
	/**
     * 按指定宽度  等比例缩放图片
     * 
     * @param imageFile
     * @param newPath
     * @param newWidth 新图的宽度
     * @throws IOException
     */
    public static void zoomImageScale(File imageFile, String newPath, int newWidth) throws IOException {
        if(!imageFile.canRead())
             return;
        BufferedImage bufferedImage = ImageIO.read(imageFile);
        if (null == bufferedImage) 
            return;
        
        int originalWidth = bufferedImage.getWidth();
        int originalHeight = bufferedImage.getHeight();
        
        double scale = (double)originalWidth / (double)newWidth;    // 缩放的比例
        
        int newHeight =  (int)(originalHeight / scale);
        
        if (newWidth > originalWidth && newHeight > originalHeight) {
        	return;
        }

        zoomImageUtils(imageFile, newPath, bufferedImage, 0, 0, newWidth, newHeight);
    }
    
    private static void zoomImageUtils(File imageFile, String newPath, BufferedImage bufferedImage, int x, int y, int width, int height)
            throws IOException{
        
         String suffix = StringUtils.substringAfterLast(imageFile.getName(), ".");
        
         // 处理 png 背景变黑的问题
        if(suffix != null && (suffix.trim().toLowerCase().endsWith("png") || suffix.trim().toLowerCase().endsWith("gif"))){
            BufferedImage to= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
            Graphics2D g2d = to.createGraphics(); 
            to = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); 
            g2d.dispose(); 
            
            g2d = to.createGraphics(); 
            Image from = bufferedImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING); 
            g2d.drawImage(from, x, y, null);
            g2d.dispose(); 
            
            ImageIO.write(to, suffix, new File(newPath));
        }else{
            // 高质量压缩，其实对清晰度而言没有太多的帮助
//            BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//            tag.getGraphics().drawImage(bufferedImage, 0, 0, width, height, null);
//
//            FileOutputStream out = new FileOutputStream(newPath);    // 将图片写入 newPath
//            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
//            JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(tag);
//            jep.setQuality(1f, true);    //压缩质量, 1 是最高值
//            encoder.encode(tag, jep);
//            out.close();
            
            BufferedImage newImage = new BufferedImage(width, height, bufferedImage.getType());
            Graphics g = newImage.getGraphics();
            g.drawImage(bufferedImage, x, y, width, height, null);
            g.dispose();
            ImageIO.write(newImage, suffix, new File(newPath));
        }
    }
    
    /**
     * 等比例改变图片尺寸
     * @param nw 新图片的宽度
     * @param oldImage 原图片
     * @throws IOException
     */
    public static void constrainProportios(int nw, String oldImage) throws IOException {
        AffineTransform transform = new AffineTransform();
        BufferedImage bis = ImageIO.read(new File(oldImage));
        int w = bis.getWidth();
        int h = bis.getHeight();
        int nh = (nw * h) / w;
        double sx = (double) nw / w;
        double sy = (double) nh / h;
        transform.setToScale(sx, sy);
        AffineTransformOp ato = new AffineTransformOp(transform, null);
        BufferedImage bid = new BufferedImage(nw, nh, BufferedImage.TYPE_3BYTE_BGR);
        ato.filter(bis, bid);
        
        String newPath = StringUtils.substringBeforeLast(oldImage,".")+"_3."+StringUtils.substringAfterLast(oldImage,".");
        ImageIO.write(bid, "jpeg", new File(newPath));
//        ImageIO.write(bid, "jpeg", response.getOutputStream());
    }
    
    /**
     * 按尺寸缩放图片
     * 
     * @param imageFile
     * @param newPath
     * @param times
     * @throws IOException
     */
    public static void zoomImage(File imageFile, String newPath, int width, int height) throws IOException {
        if (imageFile != null && !imageFile.canRead())
            return;
        BufferedImage bufferedImage = ImageIO.read(imageFile);
        if (null == bufferedImage) 
            return;

        zoomImageUtils(imageFile, newPath, bufferedImage, 0, 0, width, height);
    }
    
    /**
     * Description: 根据原图与裁切size截取局部图片
     * @param srcImg 源图片
     * @param output 图片输出流
     * @param rect 需要截取部分的坐标和大小
     */
    public static void cutImage(File srcImg, OutputStream output,java.awt.Rectangle rect) {
        if (srcImg.exists()) {
            java.io.FileInputStream fis = null;
            ImageInputStream iis = null;
            try {
                fis = new FileInputStream(srcImg);
                // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG,
                // JPEG, WBMP, GIF, gif]
                String types = Arrays.toString(ImageIO.getReaderFormatNames()).replace("]", ",");
                String suffix = null;
                // 获取图片后缀
                if (srcImg.getName().indexOf(".") > -1) {
                    suffix = srcImg.getName().substring(srcImg.getName().lastIndexOf(".") + 1);
                }// 类型和图片后缀全部小写，然后判断后缀是否合法
                if (suffix == null
                        || types.toLowerCase().indexOf(suffix.toLowerCase() + ",") < 0) {
                    //log.error("Sorry, the image suffix is illegal. the standard image suffix is {}."+ types);
                    return;
                }
                // 将FileInputStream 转换为ImageInputStream
                iis = ImageIO.createImageInputStream(fis);
                // 根据图片类型获取该种类型的ImageReader
                ImageReader reader = ImageIO.getImageReadersBySuffix(suffix).next();
                reader.setInput(iis, true);
                ImageReadParam param = reader.getDefaultReadParam();
                param.setSourceRegion(rect);
                BufferedImage bi = reader.read(0, param);
                ImageIO.write(bi, suffix, output);
                //log.info("图片生成成功，请到目录下查看");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fis != null)
                        fis.close();
                    if (iis != null)
                        iis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //log.warn("the src image is not exist.");
        }
    }


    //生成目标文件路径
    public static void cutImage(File srcImg, String destImgPath,java.awt.Rectangle rect) {
    	try {
            cutImage(srcImg,new java.io.FileOutputStream(destImgPath), rect);
        } catch (FileNotFoundException e) {
            //log.warn("the dest image is not exist.");
        }
    	
//        File destImg = new File(destImgPath);
//        if (destImg.exists()) {
//            String p = destImg.getPath();
//            try {
//                if (!destImg.isDirectory())
//                    p = destImg.getParent();
//                if (!p.endsWith(File.separator))
//                    p = p + File.separator;
//                cutImage(srcImg,new java.io.FileOutputStream(p + DEFAULT_CUT_PREVFIX+ "_"+ srcImg.getName()), rect);
//            } catch (FileNotFoundException e) {
//                //log.warn("the dest image is not exist.");
//            }
//        } //else
//            //log.warn("the dest image folder is not exist.");
    }


    public static void cutImage(String srcImg, String destImg, int x, int y, int width, int height) {
        cutImage(new File(srcImg), destImg, new java.awt.Rectangle(x, y, width, height));
    }


    public static void test_cut() {
        cutImage("C:/Users/cm/Desktop/我的页面/images/boyNoImg.jpg", "C:/Users/cm/Desktop/我的页面/images/imgs",0, 0, 61, 166);
        cutImage("C:/Users/cm/Desktop/Jcrop-master/demos/demo_files/sago.jpg", "C:/Users/cm/Desktop/我的页面/images/imgs",124, 110, 196, 176);
    }
    
    public static void makeZoomImage(File sourceFile, String newFileFullName, int w, int h) {
    	if(!sourceFile.canRead()) return;
    	try {
        	BufferedImage bufferedImage = ImageIO.read(sourceFile);
        	if (null == bufferedImage) return;
        	
        	int x = 0, y = 0, newWidth = w, newHeight = h;
    	   
        	int originalWidth = bufferedImage.getWidth();
            int originalHeight = bufferedImage.getHeight();
            
            if (w > originalWidth && h > originalHeight) 
            	return;
            
            if (w < originalWidth && h < originalHeight) {
            	double scale = (double)originalWidth / (double)newWidth;    // 缩放的比例
                newHeight =  (int)(originalHeight / scale);
                zoomImageUtils(sourceFile, newFileFullName, bufferedImage, 0, 0, newWidth, newHeight);
            	return;
            }
            
            if (w<originalWidth) { x = (originalWidth - w)/2; } else { newWidth = originalWidth;  }
            
            if (h<originalHeight) { h = (originalHeight - h)/3; }else { newHeight = originalHeight; }
            
        	cutImage(sourceFile, new java.io.FileOutputStream(newFileFullName), new java.awt.Rectangle(x, y, newWidth, newHeight));

    	}catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
